#include "pm_ehash.h"
#include <iostream>
#include <fstream>
#include <cassert>
#include <string>
#include <dirent.h>
#include <stdio.h>
#include<sstream>
#include <algorithm>
 #include <stdlib.h>
 #include<ctime>
#define PATH "../workloads/"

using namespace std;

void split(string &s, vector<string> &list,char c) {
	istringstream tmp_string(s);
	string ss;
	while (getline(tmp_string, ss, c))
	{
		list.push_back(ss);
	}

}

u_int64_t atoi(string num) {
    u_int64_t key = 0;
    for (int i = 0; i < 8; ++i) {
        key = key * 10 + num[i] - '0';
    }
    return key;
}

void readTxt(string file, u_int64_t &number, PmEHash *ehash, double & time,
    u_int64_t& i, u_int64_t& r, u_int64_t& u, u_int64_t& d) {
    ifstream infile;
    infile.open(file.data());   //将文件流对象与文件连接起来
    assert(infile.is_open());   //若失败,则输出错误消息,并终止程序运行

    string s;
    while(getline(infile, s)) {
        clock_t  start, end;
        ++number;
        vector<string> list;
        u_int64_t val;
        split(s,list,' ');
        start = clock();
        if (list[0] == "INSERT") {
            ehash->insert({atoi(list[1]),number});
            ++i;
        }
        else if (list[0] == "READ") {
            ehash->search(atoi(list[1]),val);
            ++r;
        }
        else if (list[0] == "UPDATE") {
            ehash->update({atoi(list[1]),number});
            ++u;
        }
        else if (list[0] == "REMOVE") {
            ehash->remove(atoi(list[1]));
            ++d;
        }
        else {

            cout << "op error" << endl;
        }
        end = clock();
        time += (double)(end - start) / CLOCKS_PER_SEC;

    }
    infile.close();             //关闭文件输入流
}



void test(string loadName, string runName) {
    PmEHash* ehash = new PmEHash;
    u_int64_t i = 0;
    string lpath = PATH + loadName;
    string rpath = PATH + runName;
    vector<string> list;
	split(loadName, list, '-');
	double l = 0,r = 0;
    u_int64_t li = 0,lr = 0,lu = 0,ld = 0;
    readTxt(lpath,i,ehash,l,li,lr,lu,ld);
    i = 0,li = 0,lr = 0,lu = 0,ld = 0;
    readTxt(rpath,i,ehash,r,li,lr,lu,ld);
    ehash->selfDestory();
    cout << "[ load  time  ] " << l * 1000 << "ms" << endl;
    cout << "[  run  time  ] " << r * 1000 << "ms" << endl;
    cout << "[total operand] " << i << endl;
    cout << "[I   R   U   D] " << li << " : " << lr << " : " << lu << " : " << ld << endl;
    cout << "[     OPS     ] " << i / r << endl;
}

int main()
{
    DIR *dir;
    struct dirent *ptr;
    string path = PATH;
    dir = opendir(path.c_str());
    vector <string> fileName;
    while((ptr = readdir(dir)) != NULL) {
        fileName.push_back(ptr->d_name);
    }
    sort(fileName.begin(),fileName.end());

    for (int i = 2; i < fileName.size(); i += 2) {
        //test(fileName[i],fileName[i+1]);
        cout << "**************************************" << endl;
        cout << "[    load     ] " << fileName[i] << endl;
        cout << "[    test     ] " << fileName[i + 1] << endl;
        test(fileName[i],fileName[i + 1]);
        cout << "**************************************" << endl;
        cout << endl;
    }

}
